﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PServiceBus.Services.Gateway.Runtime;
using PServiceBus.WCF.NetTcpTransport;
using PServiceBus.Core.Runtime.Transports;
using NetTcpServer;
using System.Diagnostics;

namespace NetTcpCommunication {
    public class NetTcpCommunicationTopic {
        public TestData NetTcpMessage { get; set; }
        public string NetTcpText { get; set; }
        public Dictionary<string, ArrayData> NetList { get; set; }
    }

    class Program {
        static void Main(string[] args) {
            Environment.CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory;
            var process = Process.Start("NetTcpServer.exe");
            AppDomain.CurrentDomain.ProcessExit += (s, e) => { 
                if(!process.HasExited) process.Kill();
            };
            ESB.Authenticate("rpgmaker", "password1");

            //Register NetTcp Serializer
            PServiceBus.WCF.NetTcpTransport.SerializationBootstrapper.Configure();
            
            const string topicName = "NetTcpCommunicationTopic";
            const string subscriberName = "NetTcpCommunicationSubscriber";


            var transportAction = new Action<NetTcpTransport>(t =>
                 {
                     t.EndpointAddress = "net.tcp://localhost:1234/NetTcpService";
                     t.Binding = new BindingInfo();
                     t.Format = TransportFormat.Json;
                     t.DefaultNamespaceTo("http://schemas.datacontract.org/2004/07/NetTcpServer");
                     t.MethodParameters = new List<OperationParameter>() { 
                                 new OperationParameter(){ MessagePropertyName = "NetTcpMessage", Name = "value"},
                                 new OperationParameter(){ MessagePropertyName = "NetTcpText", Name = "value2"},
                                 new OperationParameter(){ MessagePropertyName = "NetList", Name = "list"}
                             };
                     t.OperationContext = OperationCallInfo.Select<INetTcpServer>(t, "TestMethod");
                 });

            var transport = Transport.New<NetTcpTransport>(transportAction);


            if (!Topic.Exists<NetTcpCommunicationTopic>())
                Topic.Register<NetTcpCommunicationTopic>();

            var subscriber = Subscriber.New(subscriberName)
                .SubscribeTo(Topic.Select<NetTcpCommunicationTopic>())
                 .AddTransport("NetTcp", transport, topicName);

            subscriber.Save();

            
            Console.WriteLine("Type anything and Press enter to send NetTcpCommunication Message. Type exit to close window");
            var counter = 0;
            while (true) {
                var text = Console.ReadLine();
                if (text.ToLower() == "exit") break;
                var msg = new NetTcpCommunicationTopic()
                {
                    NetTcpMessage = new TestData()
                    {
                        Data = text,
                        Value = ++counter,
                        Complex = new TestComplex()
                        {
                            ComplexData = text + "Complex",
                            Values = new List<ArrayData>() { 
                                new ArrayData() { Value = 1 },
                                new ArrayData(){ Value = 2},
                                new ArrayData(){ Value = 3},
                                new ArrayData(){ Value = 4}
                            },
                            Inner = new TestComplexInner()
                            {
                                ComplexInnerDict = new Dictionary<string, ArrayData>(){
                                    {"Hello World", new ArrayData(){ Value = 1} },
                                    {"Hello Universe", new ArrayData(){ Value = 2} },
                                },
                                ComplexInnerData = text + "ComplexInner"
                            }
                        }
                    },
                    NetTcpText = text,
                    NetList = new Dictionary<string, ArrayData> { { "KV", new ArrayData() { Value = 10000000 } } }
                };

                Topic.PublishMessage(msg);
            }
            subscriber.Delete();
        }
    }
}
